home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freaks Macintosh Archive
/
Freaks Macintosh Archive.bin
/
Freaks Macintosh Archives
/
Cracking
/
Crack-It-Up.sit
/
Crack-It-Up
/
Crack-It-Up.rsrc
/
TEXT_136.txt
< prev
next >
Wrap
Text File
|
2000-01-29
|
17KB
|
474 lines
Tips and Tricks for Macsbug
All of us who program on the Macintosh have lots of little tricks that we
use to get our job done. Most of these are passed around via e-mail and the
Usenet News, if they are passed on at all. In an effort to collect all these
in one place for the benefit of all, I've created this page. Please submit
your tips to crawford@scruznet.com and I will add them to this page - with
proper attribution of course.
Contents
Where to get Macsbug
Are there books that teach how to use Macsbug?
Debugging Software on the Macintosh
How to get Macsbug help for free
Breaking While a Particular Application is Executing
Logging Program Execution
Logging Data in Real Time
Using Cursors to Trace Program Execution
Using Touch and Go Breakpoints with Two Monitors
Twiddling Pixels in the Menu Bar
Forcing Testers to Use Macsbug During Beta Testing
The Developer University Debugging Class
Links to Other Macsbug Pages
Where to get Macsbug
Macsbug is available via anonymous FTP from Apple Computer from here or
here. It is included with the two books below, but you will want to get
the latest version, especially if you are using a PowerPC.
Are there books that teach how to use Macsbug?
Yes, among them are:
o Othmer and Strauss, Debugging Mac Software with Macsbug,
Addison-Wesley 1991, ISBN 0201570491. Macsbug included on disk.
o Apple Computer Inc., Macsbug Reference and Debugging Guide version
6.2, Addison-Wesley 1991, ISBN 0201567687. Macsbug 6.2 included on
disk.
While you don't need to know how to write assembly code to use Macsbug
effectively, you will need to know how to read and understand it. Thus
you will also need to get assembly code reference manuals, such as:
o Kacmarcik, Optimizing PowerPC Code, Addison-Wesley 1995, ISBN
0201408392.
o Motorola, M68000UM/AD MC68000 8/16/32-Bit MPU User Manual,
Motorola Literature Distribution, 1991.
All of these books may be ordered from the Computer Literacy Bookstore.
How to get Macsbug help for free
Contributed by Bill Coderre, bc@wetware.com
1. Install Macsbug and programmer's key
2. Reboot the machine. Don't start any apps yet.
3. Hit CMD-POWER
4. type "log Macsbug Help <RETURN>"
5. type "help<RETURN>"
6. Push space until done.
7. type "log<RETURN>"
8. type "g<RETURN>"
9. Find the file called Macsbug Help on your desktop. Open it with a
text editor. Read it.
Breaking while a particular application is executing
Most applications call WaitNextEvent. While an application is
executing, a Pascal string with the name of the application is placed
at location 0x910. Thus the first four characters of the name itself
begin at location 0x911. Suppose you want to break while SimpleText is
active. Enter Macsbug and give the command:
atb WaitNextEvent 911^ = 'Simp'
then continue. You will shortly drop into Macsbug at SimpleText's
WaitNextEvent call. This is particularly useful when debugging faceless
background applications. If the application does not call
WaitNextEvent, try GetNextEvent instead.
Logging Program Execution
Contributed by Darren Giles, Terran Interactive, mars@netcom.com
Always on the lookout for useful debugging tools & tips, I'd love to
share ideas with others on the topic. I'll start out by offering a
snippet I've found very useful -- hopefully others will do the same.
One thing that's really bugged me about MacsBug on PPC is that the
stack crawl has become a much less useful tool. The snippet below gives
you the ability to keep track of a list of the last significant points
your program has visited. It's a list, not a stack, so you can also see
patterns of execution.
Hardly rocket science, but useful & easy to add. Just call
DEBUG_STUFF_INIT at startup, then insert a DEBUG_ENTRY wherever you
want. To see what's up, especially during a bad hang, just dm [the
address that DEBUG_STUFF_INIT dumped out at startup.]
The conditional compilation means that if you turn of debugging in your
final build, the release version of the program won't have any of this
code in it.
[debugstuff.h]
#define DB_ROUTINES_NBR_ENTRIES 40
#define DB_ROUTINES_CHARS 16
typedef char db_routine_entry[DB_ROUTINES_CHARS];
#if DEBUGGING
void DEBUG_ENTRY (char *txt);
void DEBUG_STUFF_INIT (char *title);
#else
#define DEBUG_ENTRY
#define DEBUG_STUFF_INIT
#endif
[debugstuff.c]
///////////////////////////////////////////////////////////////////////
////
#if DEBUGGING
void DEBUG_STUFF_INIT (char *title) {
OSErr myErr;
char txt[256];
long response;
if (!MacsBugInstalled()) {
hi_notify ("MacsBug is not installed… the debugging log will be
inaccessible.");
}
g_debug_entries= (db_routine_entry*) NewPtrClear
((DB_ROUTINES_NBR_ENTRIES+2) * DB_ROUTINES_CHARS);
memset (&g_debug_entries[0], '=', DB_ROUTINES_CHARS);
BlockMoveData (title, &g_debug_entries[0], strlen(title));
memset (&g_debug_entries[DB_ROUTINES_NBR_ENTRIES+1], '=',
DB_ROUTINES_CHARS);
sprintf (txt, "Debugging routine list is at 0x%lx;g", (long)
g_debug_entries);
c2pstr (txt);
DebugStr (txt);
}
#endif
///////////////////////////////////////////////////////////////////////
////
// This leaves a line in the debugging entry log.
// For example, important enter/exit points of routines
///////////////////////////////////////////////////////////////////////
////
#if DEBUGGING
void DEBUG_ENTRY (char *txt) {
short len;
// Move the previous entries down one
BlockMoveData (&g_debug_entries[1], &g_debug_entries[2],
(DB_ROUTINES_NBR_ENTRIES-1) * DB_ROUTINES_CHARS);
// Clear the new space
memset (&g_debug_entries[1], 0, DB_ROUTINES_CHARS);
// Copy in the new entry
len= strlen (txt);
if (len > DB_ROUTINES_CHARS) {
len= DB_ROUTINES_CHARS;
}
BlockMoveData (txt, &g_debug_entries[1], len);
}
#endif
Hope this does someone some good.
- Darren
==========================================================================
Darren Giles, Technical Director Terran Interactive
For info on Cleaner QuickTime compression, visit http://www.terran-int.com
Logging Data in Real Time
Contributed by Dave Stone, dstone@chem.utoronto.ca
I've also used conditional compilation to debug serial communications
stuff being processed at interrupt time - something like
#ifdef DEBUG_MY_ROUTINE
#define MAX_BUFFER 10000
char bufffer[MAX_BUFFER]; // or NewPtr it or something
long bufCount = 0L;
#endif
.
.
.
#ifdef DEBUG_MY_ROUTINE
if(bufCount < MAX_BUFFER) {
bufCount ++;
buffer[bufCount] = ch; // ch is a character read/written through serial
port
}
#endif
etc. Handy, because you can let it rip for a while to see if there is a
consistent pattern in the errors in ch - in my case, a stream of Midi
data through a very basic freeware Midi Driver.
Using Cursors to Trace Program Execution
Contributed by Tom Kimpton, Jostens Learning Corporation, tom@jlc.com
One technique that I have used in the past where dropping into the
debugger wasn't an option, and logging wasn't getting flushed in
time/took too long, was to create a bunch of cursors numbering 00 - 99,
and made a call to set the cursor and return the number of the previous
cursor:
routine1()
{
short oldCursor = setDebugCursor(15);
...
(void) setDebugCursor(oldCursor);
}
This way when the machine froze, the cursor would tell me what routine
it had frozen in.
Using Touch and Go Breakpoints with Two Monitors
I had a bug in which the Mac would occasionally freeze during shutdown
without the ability to get into Macsbug. It would only occur about once
in twenty reboots.
The way I dealt with this was to borrow a display card and hook two
monitors up to the Macintosh. You can use the Monitors control panel to
select which monitor will be used for Macsbug (hold the option key and
drag the happy Mac around).
I wrote a small application that just called ShutDownRestart(), and
placed it in the Startup Items folder. Thus, when the Mac came up into
the Finder it would immediately reboot. About every twenty minutes it
would freeze.
If you define a macro named FirstTime in the Debugger Prefs file,
Macsbug will execute it when it loads. I used a macro that was
something like:
swap; atr; atb shutdownrestart ";atb Newhandle ";g";g";g
or some such. The swap command caused Macsbug to be permanently left on
the second screen. That way when the crash occurred you could still see
the last few things Macsbug did. The ";g" following the a-trap break
commands tells Macsbug to continue after the break - this is a "Touch
and Go" breakpoint.
One thing you can also do inside a touch and go breakpoint is set new
breakpoints. I would take guesses on what traps might be called in the
neighborhood of the crash, and have breakpoints set on them when
ShutDownRestart was called.
Then I could leave the Mac rebooting on its own in the lab, and pop in
every half an hour to check the log, adjust the breakpoints and start
it up again.
The actual bug took about five months to find and fix.
Twiddling Pixels in the Menu Bar
Contributed by Dave Fleck, Wacom Technology Corp., dfleck@wacom.com
Here's my debugging tip.
I do drivers, and you just plain can't set a breakpoint in ADB
completion routines (freezes the keyboard so MacsBug is worthless!).
So I throw one of the routines below into the routine to see when a
piece of code gets executed.
What does it do? It "lights up" a bar (length dependant on screen
resolution) in the menu bar. So if you DotToggle(300); you get a
flashing short line in the menu bar.
void DotOn(long where) {
long *dot;
dot = (long *)(LMGetScrnBase() + where);
*dot |= -1;
}
void DotOff(long where) {
long *dot;
dot = (long *)(LMGetScrnBase() + where);
*dot &= 0;
}
void DotToggle(long where) {
long *dot;
dot = (long *)(LMGetScrnBase() + where);
*dot ^= -1;
}
dave
-----------------------------------------------------------------
Dave Fleck email:dfleck@wacom.com phone:360-750-8882x154
Wacom Technology Corp. sales@wacom.com
501 S.E. Columbia Shores Blvd, #300 support@wacom.com
Vancouver, WA 98661 WWW/FTP:wacom.com
------------------------------------------------------------------
Forcing Testers to Use Macsbug During Beta Testing
Contributed by Harold Ekstrom, the ag group, inc., ekstrom@aggroup.com.
Don't you just hate it when beta testers say "it crashes" but don't
give you any more information? First, tell them to use the "stdlog"
command in MacsBug, then force them to install MacsBug by checking for
it during your program's initialization:
--- DebugUtils.h ---
#pragma once
// Debugger types.
typedef enum DebuggerType {
kNoDebugger,
kMacsBug,
kTMON,
kOtherDebugger
} DebuggerType;
Boolean GetDebuggerInfo( DebuggerType *outDebuggerType,
UInt16 *outDebuggerSignature );
--- DebugUtils.c ---
// Private defines for some low memory globals.
#define MacJmp ((Ptr *)0x0120) // MacsBug jumptable [pointer].
#define MacJmpByte ((UInt8 *)0x0120) // MacsBug flags in 24 bit mode [byte].
#define MacJmpFlag ((UInt8 *)0x0BFF) // MacsBug flag [byte].
// Debugger flag bits.
#define kDebuggerInstalledBit 5
//
---------------------------------------------------------------------------------
//
//
---------------------------------------------------------------------------------
Boolean
GetDebuggerInfo(
DebuggerType * outDebuggerType,
UInt16 * outDebuggerSignature )
{
Boolean theResult = false;
SInt32 theResponse;
// Initialize return values to defaults.
*outDebuggerType = kNoDebugger;
*outDebuggerSignature = ' ';
if ( Gestalt( gestaltAddressingModeAttr, &theResponse ) == noErr ) {
UInt16 theDebugFlags;
// As documented in the "Macsbug Reference & Debugging Guide", page 412
// if we have a 32 bit capable Memory Manager, debugger flags are at 0x0BFF
// if we have a 24 bit capable Memory Manager, debugger flags are at 0x0120
if ( (theResponse & (1L << gestalt32BitCapable)) != 0 ) {
theDebugFlags = *MacJmpFlag;
} else {
theDebugFlags = *MacJmpByte;
}
if ( (theDebugFlags & (1L << kDebuggerInstalledBit)) != 0 ) {
Ptr theDebuggerEntry;
Ptr theROMBaseWorld;
// There is a debugger installed.
theResult = true;
// Get the debugger entry.
theDebuggerEntry = StripAddress( *MacJmp );
// Get the ROM base.
theROMBaseWorld = StripAddress( LMGetROMBase() );
// Compare the debugger entry to the ROM base.
if ( theDebuggerEntry < theROMBaseWorld ) {
UInt16 **theDebuggerWorld;
// It's not a ROM based debugger.
// Get the debugger world.
theDebuggerWorld = (UInt16 **) StripAddress( theDebuggerEntry - sizeof(Ptr) );
// Get the debugger signature.
*outDebuggerSignature = **theDebuggerWorld;
// Get the debugger type.
switch ( *outDebuggerSignature ) {
case 'MT':
*outDebuggerType = kMacsBug;
break;
case 'WH':
*outDebuggerType = kTMON;
break;
default:
*outDebuggerType = kOtherDebugger;
break;
}
}
}
}
return theResult;
}
Check for a low level debugger like this:
#if BETA_VERSION
DebuggerType theDebuggerType;
UInt16 theDebuggerSig;
if ( !GetDebuggerInfo( &theDebuggerType, &theDebuggerSig ) ) {
HaltRotateCursor( gRotateCrsr );
StopAlert( go_get_macsbug_alrt, nil );
ExitToShell();
}
#endif
The Developer University Debugging Class
Contributed by Malcolm Teas, Blaze Technology, mhteas@btech.com
As the instructor and developer of Apple's Developer University class
called "Macintosh Debugging Tips and Techniques" I would like to make
sure your tips page references this class.
This class is centered around MacsBug as the easiest to learn low-level
debugger. It also covers a multitude of low-level topics like memory
maps, subroutine calling protocols, code segments and code fragments,
reading (and understanding) assembler for 68K and PPC, and many more
areas. One key area is how to avoid bugs in the first place. All the
information you need to be able to debug software at the low-level.
The class is available from Apple's Developer University.
Another thing I want to mention is the version number of the most
current MacsBug is 6.5.3 (as of this writing). This version includes
the PPC commands and features.
[I have taken this class and recommend it highly - Mike]
Links to Other Macsbug Pages
o Cool MacsBug Tricks (an informal guide)
o Macsbug Use
o Develop Issue 22: Balance of Power: MacsBug for PowerPC
o Macsbug 6.5.2 Help
o Macintosh Programming Books
o Guide to Mac Tools
o Macintosh Technical Q&A's
o comp.sys.mac.programming FAQ
o Macintosh Testing and Quality Control Tools
o Development and Debugging Tools for the Macintosh